#include<Lcode/l_main.h>
#include"../share/predicat.h"

//it is  assumed that the dest and src operand format is consistent with LCODE ,the following must be ok:
//1. the dest is reg
//2. src is reg 
void before_annotate_test(L_Func * fn)
{
	L_Cb * cb;
	L_Oper * oper;
	int i ;
	for( cb = fn->first_cb; cb != NULL; cb = cb->next_cb)
	{
		for( oper = cb->first_op; oper != NULL; oper = oper->next_op)
		{
			if( oper->opc == Lop_DEFINE)
				continue;
			if( L_find_attr(oper->attr,"bw_opti_new"))
			{
				if( oper->opc != Lop_MOV )
					L_punt("error, the opti_new_oper must be mov");
			}
				
			switch(oper->opc)
			{
				case Lop_LD_UC:
				case Lop_LD_C:
				case Lop_LD_UC2:
				case Lop_LD_C2:
				case Lop_LD_F:
				case Lop_LD_I:
				case Lop_LD_UI:
				case Lop_LD_F2:
				case Lop_LD_Q:
				
				case Lop_ST_C :
				case Lop_ST_C2 :             
				case Lop_ST_I  :            
				case Lop_ST_Q  :           
				case Lop_ST_F  :          
				case Lop_ST_F2 :         
				{
				for( i = 0; i <2 ; i++)
				{
					if( !L_is_register(oper->src[i]))
						continue;
					if(!bw_is_addr_reg(oper->src[i]))
					{
						L_punt("oper: %d ,the src[%d] operand is expected addr_reg", oper->id, i);
					}
				}
				for( ;i < L_max_src_operand;i++  )
				{
					if( !L_is_register(oper->src[i]))
						continue;
					if(bw_is_addr_reg(oper->src[i]))
					{
						L_punt("oper: %d, the src[%d] operand is expected not addr_reg",oper->id, i);
					}
				}
				for( i = 0; i < L_max_dest_operand; i++)
				{
					if(!L_is_register(oper->dest[i]))
						continue;
					if(bw_is_addr_reg(oper->dest[i]))
					{
						L_punt("oper: %d , the dest[%d] operand is expected not addr_reg", oper->id, i);
					}
				}
				}
				break;
				case Lop_MOV:
				{
					if( bw_is_addr_reg(oper->src[0]))
					{
						if( bw_is_addr_reg(oper->dest[0]))
							L_punt("oper : %d , src, and dest is addr reg is not expected",oper->id);
					}
				}
				break;
				case Lop_ADD:
				case Lop_ADD_U:
				case Lop_SUB:
				case Lop_SUB_U:
				{
					int dest_is_addr = 0;
					if( bw_is_addr_reg(oper->dest[0]))
						dest_is_addr = 1;	
					for(i = 0; i < L_max_src_operand; i++)
					{
						if( ! L_is_register(oper->src[i]))
							continue;
						if((bw_is_addr_reg(oper->src[i]) && !dest_is_addr)||
							(bw_is_data_reg(oper->src[i]) && dest_is_addr))
						{
							L_punt("oper: %d , the src and dest should be consistent reg_type",oper->id);
						}
					}
				}
				break;
				default:
				{
					for( i = 0; i < L_max_src_operand; i++)
					{
						if( !L_is_register(oper->src[i] ))
							continue;
						if(bw_is_addr_reg(oper->src[i]))
							L_punt("oper: %d , operand %d  is expected no addr_reg",oper->id, i);
					}
					for( i = 0; i < L_max_dest_operand; i++)
					{
						if( ! L_is_register(oper->src[i]))
							continue;
						if( bw_is_addr_reg(oper->dest[i]))
						{
							L_punt("oper: %d, operand %d 	is expected not addr_reg", oper->id, i);
						}	
					}
				}
			}
		}
	}
}










